package com.ruoyi.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.app.domain.AppDetail;
import com.ruoyi.app.domain.AppPackage;
import com.ruoyi.app.domain.vo.AppPackageVo;
import com.ruoyi.app.service.*;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.enums.BillType;
import com.ruoyi.common.enums.CoinType;
import com.ruoyi.common.enums.DetailEnums;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.EntityCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.redis.RedisUtils;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.app.domain.bo.AppPackageOrderBo;
import com.ruoyi.app.domain.vo.AppPackageOrderVo;
import com.ruoyi.app.domain.AppPackageOrder;
import com.ruoyi.app.mapper.AppPackageOrderMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * APP用户套餐订单Service业务层处理
 *
 * @author ruoyi
 * @date 2025-06-21
 */
@RequiredArgsConstructor
@Service
public class AppPackageOrderServiceImpl implements IAppPackageOrderService {

    private final AppPackageOrderMapper baseMapper;
    private final IAppAssetService appAssetService;
    private final IAppDetailService appDetailService;
    private final IAppUserService appUserService;
    private final IAppUserCodeService iAppUserCodeService;

    /**
     * 查询APP用户套餐订单
     */
    @Override
    public AppPackageOrderVo queryById(Long packageOrderId) {
        return baseMapper.selectVoById(packageOrderId);
    }

    /**
     * 查询APP用户套餐订单列表
     */
    @Override
    public TableDataInfo<AppPackageOrderVo> queryPageList(AppPackageOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<AppPackageOrder> lqw = buildQueryWrapper(bo);
        Page<AppPackageOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        if (!CollUtil.isEmpty(result.getRecords())){
            for (AppPackageOrderVo record : result.getRecords()) {
                BigDecimal packageIncome = record.getPackageIncome();
                BigDecimal nowIncome = record.getNowIncome();
                record.setDaiIncome(packageIncome.subtract(nowIncome).toString());
            }
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询APP用户套餐订单列表
     */
    @Override
    public List<AppPackageOrderVo> queryList(AppPackageOrderBo bo) {
        LambdaQueryWrapper<AppPackageOrder> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public List<AppPackageOrderVo> queryWrapper(LambdaQueryWrapper<AppPackageOrder> wrapper) {
        return baseMapper.selectVoList(wrapper);
    }

    private LambdaQueryWrapper<AppPackageOrder> buildQueryWrapper(AppPackageOrderBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<AppPackageOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getPackageOrderId() != null, AppPackageOrder::getPackageOrderId, bo.getPackageOrderId());
        lqw.eq(bo.getPackageId() != null, AppPackageOrder::getPackageId, bo.getPackageId());
        lqw.eq(bo.getUserId() != null, AppPackageOrder::getUserId, bo.getUserId());
        lqw.like(StringUtils.isNotBlank(bo.getPackageName()), AppPackageOrder::getPackageName, bo.getPackageName());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), AppPackageOrder::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增APP用户套餐订单
     */
    @Override
    public Boolean insertByBo(AppPackageOrderBo bo) {
        AppPackageOrder add = BeanUtil.toBean(bo, AppPackageOrder.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setPackageOrderId(add.getPackageOrderId());
        }
        return flag;
    }

    /**
     * 修改APP用户套餐订单
     */
    @Override
    public Boolean updateByBo(AppPackageOrderBo bo) {
        AppPackageOrder update = BeanUtil.toBean(bo, AppPackageOrder.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByVo(AppPackageOrderVo vo) {
        AppPackageOrder update = BeanUtil.toBean(vo, AppPackageOrder.class);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AppPackageOrder entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除APP用户套餐订单
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean deleteWithValidById(Long id) {
        return baseMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createTask(AppPackageVo appPackageVo, Long id) {
        appAssetService.subtractIntegral(id, appPackageVo.getPackagePrice());
        AppPackageOrderBo orderBo = new AppPackageOrderBo();
        EntityCopyUtils.copyPropertiesIgnoreNull(appPackageVo, orderBo);
        orderBo.setUserId(id);
        orderBo.setNowIncomeDay(0L);
        orderBo.setNowIncome(BigDecimal.ZERO);
        orderBo.setStatus(Constants.SUCCESS);
        DateTime dateTime = DateUtil.offsetDay(new Date(), appPackageVo.getIncomeMaxDay().intValue());
        orderBo.setEndTime(dateTime);
        orderBo.setCreateTime(DateUtils.getNowDate());
        if (insertByBo(orderBo)) {
            appDetailService.insert(id, appPackageVo.getPackagePrice(), BigDecimal.ZERO,
                    BillType.TO.getCode(), CoinType.INTE.getCode(),
                    DetailEnums.BUY_TASK.getCode(), "购买任务包" + appPackageVo.getPackageName(), null);


            //检查是否重复购买任务包 如果重复 则赠送5个贡献度 加1活跃度
            AppPackageOrderBo appPackageOrderBo = new AppPackageOrderBo();
            appPackageOrderBo.setUserId(id);
            appPackageOrderBo.setPackageId(appPackageVo.getPackageId());
            List<AppPackageOrderVo> list = queryList(appPackageOrderBo);
            if (appPackageVo.getPackageId()!=1){
                if (!CollUtil.isEmpty(list) && !list.isEmpty()){
                    if (list.size()>1){
                        //复购获得额外差额的贡献值
                        AppPackageOrderVo appPackageOrderVo = list.get(0);
                        BigDecimal contribution = appPackageOrderVo.getPackageIncome().subtract(appPackageOrderVo.getPackagePrice());
                        if (contribution.compareTo(BigDecimal.ZERO) > 0){
                            appAssetService.addContribution(id, contribution);
                            appDetailService.insert(id, contribution, BigDecimal.ZERO,
                                    BillType.IN.getCode(), CoinType.CONTRIBUTION.getCode(),
                                    DetailEnums.RECHARGE_REWARD.getCode(), appPackageVo.getPackageName()+"-复购奖励", null);

                        }
                    }
                }
            }


            //初始化第一天收益
            initPackageIncome(id, orderBo);


            return true;
        }
        return false;
    }

    public void initPackageIncome(Long id, AppPackageOrderBo e) {
        long day = e.getNowIncomeDay() + 1;
        e.setNowIncomeDay(day);
        BigDecimal income = e.getPackageIncome().divide(new BigDecimal(e.getIncomeDay()), 2, RoundingMode.HALF_UP);
        e.setNowIncome(e.getNowIncome().add(income));
        AppPackageOrderVo appPackageOrderVo = new AppPackageOrderVo();
        EntityCopyUtils.copyPropertiesIgnoreNull(e, appPackageOrderVo);
        if (updateByVo(appPackageOrderVo)) {
            appAssetService.addIntegral(id, income);
            appDetailService.insert(id, income, BigDecimal.ZERO, BillType.IN.getCode(), CoinType.INTE.getCode(),
                    DetailEnums.BUY_TASK_REWARD.getCode(), e.getPackageName() + "收益", null);
            //完成任务包 给推荐人收益 直推30% 间推15% 针对的是非第一层
            if (e.getPackagePrice().compareTo(BigDecimal.ZERO) > 0) {
                appUserService.pageOrderRewards(id, income, e.getPackageName());
            }
            //增加活跃度 前提是活跃度 未曾加过
            appAssetService.addLiveIfAbsent(id, 1);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean sendTask(AppPackageVo appPackageVo, Long id) {
        AppPackageOrderBo orderBo = new AppPackageOrderBo();
        EntityCopyUtils.copyPropertiesIgnoreNull(appPackageVo, orderBo);
        orderBo.setUserId(id);
        orderBo.setNowIncomeDay(0L);
        orderBo.setNowIncome(BigDecimal.ZERO);
        orderBo.setStatus(Constants.SUCCESS);
        DateTime dateTime = DateUtil.offsetDay(new Date(), appPackageVo.getIncomeMaxDay().intValue());
        orderBo.setEndTime(dateTime);
        orderBo.setCreateTime(DateUtils.getNowDate());
        if (insertByBo(orderBo)) {
            appAssetService.addLiveness(id, appPackageVo.getPackageLiveness());
            appDetailService.insert(id, appPackageVo.getPackageLiveness(),
                    BigDecimal.ZERO, BillType.IN.getCode(), CoinType.LIVENESS.getCode(),
                    DetailEnums.BUY_TASK_REWARD.getCode(), "任务包" + appPackageVo.getPackageName() + "奖励活跃度", null);
            return true;
        }
        return false;
    }

    /**
     * 每日任务包完成
     *
     * @param id 用户ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dayDownOrder(Long id) {
        String key = CacheConstants.TODAY_TASK_DOWN + id;
        RedisUtils.setCacheObject(key, Constants.SUCCESS, Duration.ofSeconds(DateUtils.seconds()));
        AppPackageOrderBo orderBo = new AppPackageOrderBo();
        orderBo.setUserId(id);
        orderBo.setStatus(Constants.SUCCESS);
        List<AppPackageOrderVo> orderVos = queryList(orderBo);
        for (AppPackageOrderVo e : orderVos) {
            long day = e.getNowIncomeDay() + 1;
            e.setNowIncomeDay(day);
            if (day == 30) {
                e.setStatus(Constants.FAIL);
            }
            BigDecimal income = e.getPackageIncome().divide(new BigDecimal(e.getIncomeDay()), 2, RoundingMode.HALF_UP);
            e.setNowIncome(e.getNowIncome().add(income));
            if (updateByVo(e)) {
                appAssetService.addIntegral(id, income);
                appDetailService.insert(id, income, BigDecimal.ZERO, BillType.IN.getCode(), CoinType.INTE.getCode(),
                        DetailEnums.BUY_TASK_REWARD.getCode(), e.getPackageName() + "收益", null);
                //完成任务包 给推荐人收益 直推30% 间推15% 针对的是非第一层
                if (e.getPackagePrice().compareTo(BigDecimal.ZERO) > 0) {
                    appUserService.pageOrderRewards(id, income, e.getPackageName());
                }
                //增加活跃度 前提是活跃度 未曾加过
                appAssetService.addLiveIfAbsent(id, 1);
            }
        }
    }

    @Override
    public Object queryTodaySum() {
        LambdaQueryWrapper<AppDetail> appDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 获取当前日期的 LocalDate 对象
        LocalDate today = LocalDate.now();
        // 今天开始时间（00:00:00）
        LocalDateTime startOfDay = today.atStartOfDay();
        System.out.println("今天开始时间: " + startOfDay);
        appDetailLambdaQueryWrapper.ge(AppDetail::getCreateTime, startOfDay);
        appDetailLambdaQueryWrapper.like(AppDetail::getRemark, "包收益");
        List<AppDetail> appPackageOrders = appDetailService.selectList(appDetailLambdaQueryWrapper);
        if (appPackageOrders != null){
            Map<Long, List<AppDetail>> collect = appPackageOrders.stream().collect(Collectors.groupingBy(AppDetail::getUserId));
            return collect.size();
        }
        return 0;
    }

    @Override
    public Object queryTodayNoSum() {
        LambdaQueryWrapper<AppDetail> appPackageOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 获取当前日期的 LocalDate 对象
        LocalDate today = LocalDate.now();
        // 今天开始时间（00:00:00）
        LocalDateTime startOfDay = today.atStartOfDay();
        System.out.println("今天开始时间: " + startOfDay);
        appPackageOrderLambdaQueryWrapper.ge(AppDetail::getCreateTime, startOfDay);
        appPackageOrderLambdaQueryWrapper.like(AppDetail::getRemark, "包收益");
        List<AppDetail> appPackageOrders = appDetailService.selectList(appPackageOrderLambdaQueryWrapper);
        if (appPackageOrders != null){
            //今天做任务的人
            Map<Long, List<AppDetail>> collect = appPackageOrders.stream().collect(Collectors.groupingBy(AppDetail::getUserId));
            int size = collect.size();
            //查询正在进行任务的人
            LambdaQueryWrapper<AppPackageOrder> appPackageOrderLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
            List<AppPackageOrder> appPackageOrders1 = baseMapper.selectList(appPackageOrderLambdaQueryWrapper1.eq(AppPackageOrder::getStatus, "0"));
            return iAppUserCodeService.queryAuthed() - size;
        }
        return 0;
    }

    @Override
    public Object queryYesTodaySum() {
        // 1. 获取昨日日期
        LocalDate yesterday = LocalDate.now().minusDays(1);
        // 2. 昨日的开始时间（00:00:00）
        LocalDateTime startOfYesterday = yesterday.atStartOfDay();
        Date startDate = Date.from(startOfYesterday.atZone(ZoneId.systemDefault()).toInstant());
        // 3. 昨日的结束时间（23:59:59）
        LocalDateTime endOfYesterday = yesterday.atTime(LocalTime.MAX);
        Date endDate = Date.from(endOfYesterday.atZone(ZoneId.systemDefault()).toInstant());
        LambdaQueryWrapper<AppDetail> appPackageOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appPackageOrderLambdaQueryWrapper.between(AppDetail::getCreateTime, startDate, endDate);
        appPackageOrderLambdaQueryWrapper.like(AppDetail::getRemark, "包收益");
        List<AppDetail> appPackageOrders = appDetailService.selectList(appPackageOrderLambdaQueryWrapper);
        if (appPackageOrders != null && appPackageOrders.size() > 0) {
            Map<Long, List<AppDetail>> collect = appPackageOrders.stream().collect(Collectors.groupingBy(AppDetail::getUserId));
            return collect.size();
        }
        return 0;
    }

    @Override
    public Object queryTodayNoYesSum() {
        // 1. 获取昨日日期
        LocalDate yesterday = LocalDate.now().minusDays(1);
        // 2. 昨日的开始时间（00:00:00）
        LocalDateTime startOfYesterday = yesterday.atStartOfDay();
        Date startDate = Date.from(startOfYesterday.atZone(ZoneId.systemDefault()).toInstant());
        // 3. 昨日的结束时间（23:59:59）
        LocalDateTime endOfYesterday = yesterday.atTime(LocalTime.MAX);
        Date endDate = Date.from(endOfYesterday.atZone(ZoneId.systemDefault()).toInstant());
        LambdaQueryWrapper<AppDetail> appPackageOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appPackageOrderLambdaQueryWrapper.between(AppDetail::getCreateTime, startDate, endDate);
        appPackageOrderLambdaQueryWrapper.like(AppDetail::getRemark, "包收益");
        List<AppDetail> appPackageOrders = appDetailService.selectList(appPackageOrderLambdaQueryWrapper);
        //今天做任务的人
        Map<Long, List<AppDetail>> collect = appPackageOrders.stream().collect(Collectors.groupingBy(AppDetail::getUserId));
        int size = collect.size();
        LambdaQueryWrapper<AppPackageOrder> appPackageOrderLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        List<AppPackageOrder> appPackageOrders1 = baseMapper.selectList(appPackageOrderLambdaQueryWrapper1.eq(AppPackageOrder::getStatus, "0"));
        return iAppUserCodeService.queryAuthed() - size;
    }

    @Override
    public List<AppPackageOrder> getPageOrder(List<Long> collect) {
        LambdaQueryWrapper<AppPackageOrder> appPackageOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        appPackageOrderLambdaQueryWrapper.in(AppPackageOrder::getUserId, collect);
        appPackageOrderLambdaQueryWrapper.eq(AppPackageOrder::getStatus, "0");
        return baseMapper.selectList(appPackageOrderLambdaQueryWrapper);
    }

    @Override
    public void sendPackage(AppPackage appPackage, Long id) {
        AppPackageOrderBo orderBo = new AppPackageOrderBo();
        EntityCopyUtils.copyPropertiesIgnoreNull(appPackage, orderBo);
        orderBo.setUserId(id);
        orderBo.setNowIncomeDay(0L);
        orderBo.setNowIncome(BigDecimal.ZERO);
        orderBo.setStatus(Constants.SUCCESS);
        DateTime dateTime = DateUtil.offsetDay(new Date(), appPackage.getIncomeMaxDay().intValue());
        orderBo.setEndTime(dateTime);
        orderBo.setCreateTime(DateUtils.getNowDate());
        if (insertByBo(orderBo)) {
            appDetailService.insert(id, appPackage.getPackagePrice(), BigDecimal.ZERO,
                    BillType.TO.getCode(), CoinType.INTE.getCode(),
                    DetailEnums.BUY_TASK.getCode(), "升星送出任务包:" + appPackage.getPackageName(), null);
        }
        //初始化第一天收益
        initPackageIncome(id, orderBo);
    }
}
